﻿// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "UObject/Object.h"
#include "AbstractFactoryPattern.generated.h"

/**	抽象工厂模式 Abstract Factory Pattern
 *	描述
 *		提供一个创建一系列相关或相互依赖对象的接口，而无须指定它们具体的类；具体的工厂负责实现具体的产品实例
 *		抽象工厂中每个工厂可以创建多种产品（如苹果公司生产iPhone、iPad）；
 *		工厂方法每个工厂只能创建一种
 *	三种工厂小结
 *		假设有骷髅士兵、骷髅弓箭手、哥布林士兵、哥布林弓箭手四种怪物
 *			简单工厂模式
 *				一个工厂有四个方法创建骷髅士兵、骷髅弓箭手、哥布林士兵、哥布林弓箭手
 *			工厂方法模式
 *				四个工厂： 骷髅士兵工厂、骷髅弓箭手工厂、哥布林士兵工厂、哥布林弓箭手工厂，每个工厂创建对应的怪物
 *			抽象工厂模式
 *				两个工厂： 骷髅怪物工厂 负责创建骷髅士兵、骷髅弓箭手；哥布林工厂，负责创建困难哥布林士兵、哥布林弓箭手。
 *	套路
 *		创建抽象产品族类 ，定义抽象产品的公共接口；
 *		创建抽象产品类 ，继承抽象产品族类；（此处可理解为相对具体得产品族类）
 *		创建具体产品类，继承抽象产品类；
 *		创建抽象工厂类
 *		创建工厂类，继承抽象工厂类，定义具体产品类的创建方法；
 *		通过调用具体工厂类的方法，从而创建不同具体产品类的实例
 *	使用场景
 *		一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节，这对于所有类型的工厂模式都是重要的。
 *		系统中有多个产品族，每次只使用其中某一产品族。
 *		属于同一个产品族的产品将在一起使用，这一约束必须在系统的设计中体现出来。
 *		系统提供一个产品类的库，所有的产品以同样的接口出现，从而使客户端不依赖于具体实现。
 *		举例
 *			敌人生成，不同区域地点可以利用不同工厂生成不同敌人，
 *			游戏难度，不同难度可以产生不同类型的建筑、英雄以及技能。
 *			AI 战术选择。实现确定好几种可选战术作为产品族，每种战术按照类似海军、空军、陆军作为产品等级结构选择具体兵种进行生产建造。
 *			多语言。用户改变语言环境时，会改变响应的文字显示，音效，图片显示，操作习惯适配等。
 *			皮肤更换或者资源管理。用户选择不同主题的皮肤将会影响图片显示以及动画效果。
 *			屏幕适配。对高、中、低分辨率的移动设备使用不同的显示资源。
 *	优缺点
 *		优点
 *			隔离了具体类的生成，使得调用者不需要知道什么被创建。所有的具体工厂都实现了抽象工厂中定义的那些公共接口，因此只需改变具体工厂的实例，就可以在某种程度上改变整个软件系统的行为。实现了高内聚低耦合
 *			所有的具体工厂都实现了抽象工厂中定义的那些公共接口，因此只需改变具体工厂的实例，就可以在某种程度上改变整个软件系统的行为。
 *			增加新的具体工厂和产品族很方便，无须修改已有系统，符合“开闭原则”。
 *		缺点
 *			在添加新的产品对象时，难以扩展抽象工厂来生产新种类的产品，这是因为在抽象工厂角色中规定了所有可能被创建的产品集合，要支持新种类的产品就意味着要对该接口进行扩展，而这将涉及到对抽象工厂角色及其所有子类的修改，显然会带来较大的不便。
 *			开闭原则的倾斜性（增加新的工厂和产品族容易，增加新的产品等级结构麻烦）。
 **/

/**
 *	怪物抽象类
 *		士兵抽象类
 *			骷髅士兵
 *			哥布林士兵
 *		弓箭手
 *			骷髅弓箭手
 *			哥布林弓箭手
 *	怪物生成器抽象类
 *		不死族地带怪物生成器
 *		哥布林地带怪物生成器
 **/

// 抽象产品族类 —— 怪物
UCLASS(Abstract)
class MISCELLANEOUSPROJECT_API UMonster : public UObject
{
	GENERATED_BODY()
public:
	virtual void ShowInfo()
	{
		check(0 && "You must override this");
	}
};

// 抽象产品类、具体产品族 —— 怪物士兵
UCLASS(Blueprintable, BlueprintType)
class MISCELLANEOUSPROJECT_API UMonsterSoldier : public UMonster
{
	GENERATED_BODY()
public:
	virtual void ShowInfo() override
	{
		// UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" This is a Monster Soldier"));
	}
};

// 抽象产品类、具体产品族 —— 怪物弓箭手
UCLASS(Blueprintable, BlueprintType)
class MISCELLANEOUSPROJECT_API UMonsterArcher : public UMonster
{
	GENERATED_BODY()
public:
	virtual void ShowInfo() override
	{
		// UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" This is a Monster Archer"));
	}
};

// 具体产品类 —— 怪物士兵 —— 骷髅士兵
UCLASS(Blueprintable, BlueprintType)
class MISCELLANEOUSPROJECT_API UUndeadSkeletonSoldier : public UMonsterSoldier
{
	GENERATED_BODY()
public:
	virtual void ShowInfo() override
	{
		// UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" This is a Undead Skeleton Soldier"));
	}
};

// 具体产品类 —— 怪物士兵 —— 哥布林士兵
UCLASS(Blueprintable, BlueprintType)
class MISCELLANEOUSPROJECT_API UGoblinSoldier : public UMonsterSoldier
{
	GENERATED_BODY()
public:
	virtual void ShowInfo() override
	{
		// UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" This is a Goblin Soldier"));
	}
};

// 具体产品类 —— 怪物弓箭手 —— 骷髅弓箭手
UCLASS(Blueprintable, BlueprintType)
class MISCELLANEOUSPROJECT_API UUndeadSkeletonArcher : public UMonsterArcher
{
	GENERATED_BODY()
public:
	virtual void ShowInfo() override
	{
		// UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" This is a Undead Skeleton Archer"));
	}
};

// 具体产品类 —— 怪物弓箭手 —— 哥布林弓箭手
UCLASS(Blueprintable, BlueprintType)
class MISCELLANEOUSPROJECT_API UGoblinArcher : public UMonsterArcher
{
	GENERATED_BODY()
public:
	virtual void ShowInfo() override
	{
		// UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" This is a Goblin Archer"));
	}
};

// 抽象工厂类 —— 怪物生成器
UCLASS(Abstract)
class MISCELLANEOUSPROJECT_API UMonsterFactory : public UObject
{
	GENERATED_BODY()
public:

	// 生成士兵
	virtual UMonsterSoldier* CreateMonsterSoldier()
	{
		check(0 && "You must override this");
		return nullptr;
	}

	// 生成弓箭手
	virtual UMonsterArcher* CreateMonsterArcher()
	{
		check(0 && "You must override this");
		return nullptr;
	}
};

// 具体工厂类 —— 不死族怪物生成器
UCLASS(Blueprintable, BlueprintType)
class MISCELLANEOUSPROJECT_API UUndeadMonsterFactory : public UMonsterFactory
{
	GENERATED_BODY()
public:
	// 生成骷髅士兵
	virtual UMonsterSoldier* CreateMonsterSoldier() override
	{
		return NewObject<UUndeadSkeletonSoldier>(); // 实际使用 SpawnActor
	}

	// 生成骷髅弓箭手
	virtual UMonsterArcher* CreateMonsterArcher() override
	{
		return NewObject<UUndeadSkeletonArcher>();
	}
};

// 具体工厂类 —— 哥布林怪物生成器
UCLASS(Blueprintable, BlueprintType)
class MISCELLANEOUSPROJECT_API UGoblinMonsterFactory : public UMonsterFactory
{
	GENERATED_BODY()
public:

	// 生成哥布林士兵
	virtual UMonsterSoldier* CreateMonsterSoldier() override
	{
		return NewObject<UGoblinSoldier>(); // 实际使用 SpawnActor
	}

	// 生成哥布林弓箭手
	virtual UMonsterArcher* CreateMonsterArcher() override
	{
		return NewObject<UGoblinArcher>();
	}
};

// 调用测试用的Actor
UCLASS()
class MISCELLANEOUSPROJECT_API AMonsterGenerator : public AActor
{
	GENERATED_BODY()
public:

	virtual void BeginPlay() override
	{
		// 不死族地带区域 生成怪物
		UUndeadMonsterFactory* UndeadMonsterFactory = NewObject<UUndeadMonsterFactory>();
		UndeadMonsterFactory->CreateMonsterSoldier()->ShowInfo();
		UndeadMonsterFactory->CreateMonsterArcher()->ShowInfo();

		// 哥布林地带生成 怪物
		UGoblinMonsterFactory* GoblinMonsterFactory = NewObject<UGoblinMonsterFactory>();
		GoblinMonsterFactory->CreateMonsterSoldier()->ShowInfo();
		GoblinMonsterFactory->CreateMonsterArcher()->ShowInfo();
	}
};
